#ifndef __ISO_STANDARD_C_H
#define __ISO_STANDARD_C_H
#include "std_C89_C99_C11_tips.h"


class help_content{
    // http://www.gnu.org/software/libc/manual/html_node/ISO-C-Threads.html#ISO-C-Threads

	//@h_assert <assert.h>	Conditionally compiled macro that compares its argument to zero
	
	//@h_complex <complex.h> (since C99)	Complex number arithmetic
	
	//@h_ctype <ctype.h> Functions to determine the type contained in character data
	
	//@h_errno <errno.h> Macros reporting error conditions
	
	//@h_fenv <fenv.h> (since C99)	Floating-point environment
	
	//@h_float <float.h> Limits of float types
	
	//@h_inttypes <inttypes.h> (since C99)	Format conversion of integer types
	
	//@h_iso646 <iso646.h> (since C95)	Alternative operator spellings
	
	//@h_limits <limits.h>	Sizes of basic types
	
	//@h_local <locale.h>	Localization utilities
	
	//@h_math <math.h>	Common mathematics functions
	
	//@h_setjmp <setjmp.h>	Nonlocal jumps
	
	//@h_signal <signal.h>	Signal handling
	
	//@h_stdalign <stdalign.h> (since C11)	alignas and alignof convenience macros
	
	//@h_stdarg <stdarg.h>	Variable arguments
	
	//@h_stdatomic <stdatomic.h> (since C11) Atomic types
	
	//@h_stdbool <stdbool.h> (since C99)	Boolean type
	
	//@h_stddef <stddef.h>	Common macro definitions
	
	//@h_stdint <stdint.h> (since C99)	Fixed-width integer types
	
	//@h_stdio <stdio.h> Input/output
	
	//@h_stdlib <stdlib.h>	General utilities: memory management, program utilities, string conversions, random numbers
	
	//@h_stdnoreturn <stdnoreturn.h> (since C11)	noreturn convenience macros
	
	//@h_string <string.h>	String handling
	
	//@h_tgmath <tgmath.h> (since C99)	Type-generic math (macros wrapping math.h and complex.h)
	
	//@h_threads <threads.h> (since C11)	Thread library
	
	//@h_time <time.h>	Time/date utilities

	//@h_uchar <uchar.h> (since C11) UTF-16 and UTF-32 character utilities
	
	//@h_wchar <wchar.h> (since C95) Extended multibyte and wide character utilities
	
	//@h_wctype <wctype.h> (since C95)	Functions to determine the type contained in wide character data

};


/********************************************************************************
                                Key Words
********************************************************************************/
class help_language{
    //  c basic keywords
	//	break
	//	case
	//	char
	//	const
	//	continue
	//	default
	//	do
	//	double
	//	else
	//	enum
	//	extern
	//	float
	//	for
	//	goto
	//	if
	//	int
	//	long
	//	return
	//	short
	//	signed
	//	sizeof
	//	static
	//	struct
	//	switch
	//	typedef
	//	union
	//	unsigned
	//	void
	//	volatile
	//	while

    //Since C99
	//	inline
	//	_Bool

    //Since C11
	//	auto
	//	fortran
	//	register
	//	restrict
	//	_Alignas
	//	_Alignof
	//	_Atomic
	//	_Complex
	//	_Generic
	//	_Imaginary
	//	_Noreturn
	//	_Static_assert
	//	_Thread_local - thread storage duration (since C11)
 
};

/********************************************************************************
                                C header
********************************************************************************/
class help_header{
/**
----Since C89
<assert.h>	     Conditionally compiled macro that compares its argument to zero
<ctype.h>	     Functions to determine the type contained in character data
<errno.h>	     Macros reporting error conditions
<float.h>	     Limits of float types
<limits.h>	     Sizes of basic types
<locale.h>	     Localization utilities
<math.h>	     Common mathematics functions
<setjmp.h>	     Nonlocal jumps
<signal.h>	     Signal handling
<stdarg.h>	     Variable arguments
<string.h>	     String handling
<stdio.h>	     Input/output
<stdlib.h>	     General utilities: memory management, program utilities, string conversions, random numbers
<time.h>	     Time/date utilities
<stddef.h>	     Common macro definitions

----Since C95 
<wchar.h>       (since C95)	Extended multibyte and wide character utilities
<wctype.h>      (since C95)	Functions to determine the type contained in wide character data
<iso646.h>      (since C95)	Alternative operator spellings

---Since C99
<complex.h>     (since C99)	Complex number arithmetic
<fenv.h>        (since C99)	Floating-point environment
<inttypes.h>    (since C99)	Format conversion of integer types
<stdbool.h>     (since C99)	Boolean type
<stdint.h>      (since C99)	Fixed-width integer types
<tgmath.h>      (since C99)	Type-generic math (macros wrapping math.h and complex.h)


---Since C11
<stdalign.h>    (since C11)	alignas and alignof convenience macros
<stdatomic.h>   (since C11)	Atomic types
<stdnoreturn.h> (since C11)	noreturn convenience macros
<threads.h>     (since C11)	Thread library
<uchar.h>       (since C11)	UTF-16 and UTF-32 character utilities
**/

};
/********************************************************************************
                                C Guide
********************************************************************************/
class help_introduce{
    // 编程指南
    // 推荐使用C89/C99/C11 特性及库函数
    // 目前普及最为广泛的还是C99 标准，支持C11的编译器很少

/**

 （1）对数组的增强

  可变长数组
    C99中,程序员声明数组时,数组的维数可以由任一有效的整型表达式确定,
    包括只在运行时才能确定
    其值的表达式,这类数组就叫做可变长数组,但是只有局部数组才可以是变长的.
    可变长数组的维数在数组生存期内是不变的,也就是说,可变长数组不是动态的.
    可以变化的只是数组的大小.
    可以使用*来定义不确定长的可变长数组。

  数组声明中的类型修饰符
　在C99中，如果需要使用数组作为函数变元，可以在数组声明的方括号内使用static关键?
这相当于告诉编译程序，变元所指向的数组将至少包含指定的元素个数。也可以在数组声明的?
括号内使用
restrict,volatile,
const关键字，但只用于函数变元。如果使用restrict，指针是初始访问该对象的惟一途
径。如果使用const，指针始终指向同一个数组。使用volatile没有任何意义。

 （2）单行注释
     引入了单行注释标记 "//" , 可以象C++一样使用这种注释了。
 （3）分散代码与声明
　　    预处理程序的修改
 （4）for语句内的变量声明　　
　　C99中，程序员可以在for语句的初始化部分定义一个或多个变量，这些变量的作用域仅?
?本for语
句所控制的循环体内。比如：
代码:
for(int i=0; i<10; i++){
    // do someting ...
}

   （5）复合赋值

C99中，复合赋值中，可以指定对象类型的数组、结构或联合表达式。当使用复合赋值时，?
?在括弧
内指定类型，后跟由花括号围起来的初始化列表；若类型为数组，则不能指定数组的大小?
?建成的对象是
未命名的。
　　例： double *fp = (double[]) {1.1, 2.2, 3.3};
　　该语句用于建立一个指向double的指针fp，且该指针指向这个3元素数组的第一个元素。
在文件
域内建立的复合赋值只在程序的整个生存期内有效。在模块内建立的复合赋值是局部对象?
?在退出模块后
不再存在。

   (6)指定的初始化符

C99中，该特性对经常使用稀疏数组的程序员十分有用。指定的初始化符通常有两种用法：?
?于数组，
以及用于结构和联合。用于数组的格式：[index] = vol;
其中，index表示数组的下标，vol表示本数组
元素的初始化值。
　　例如： int x[10] = {[0] = 10, [5] = 30}; 其中只有x[0]和x[5]得到了初始化．用于结构或联
合的格式如下：
　　member-name(成员名称)
　　对结构进行指定的初始化时，允许采用简单的方法对结构中的指定成员进行初始化。
　　例如： struct example{ int k, m, n; } object = {m = 10,n = 200};
　　其中，没有初始化k。对结构成员进行初始化的顺序没有限制。

     (7)printf()和scanf()函数系列的增强

  C99中printf()和scanf()函数系列引进了处理long long int和unsigned long long int数据类型
的特性。long long int 类型的格式修饰符是ll。在printf()和scanf()函数中，ll适用于d, i, o, u 和x
格式说明符。另外，C99还引进了hh修饰符。当使用d, i, o, u和x格式说明符时，hh用于指定char
型变元。ll和hh修饰符均可以用于n说明符。
　　格式修饰符a和A用在printf()函数中时，结果将会输出十六进制的浮点数。格式如下：[-]
0xh, hhhhp
+ d 使用A格式修饰符时，x和p必须是大写。A和a格式修饰符也可以用在scanf()
函数中，用于读取
浮点数。调用printf()函数时，允许在%f说明符前加上l修饰符，即%lf，但不起作用。

      (10)__func__预定义标识符
　　用于指出__func__所存放的函数名，类似于字符串赋值。

     (11)

       其它特性的改动
　　放宽的转换限制
　
　　　　限制　　　　　　　　　　　　　C89标准　　C99标准
　　　　数据块的嵌套层数　　　　　　　15　　　　　127
　　　　条件语句的嵌套层数　　　　　　8　　　　　 63
　　　　内部标识符中的有效字符个数　　31　　　　　63
　　　　外部标识符中的有效字符个数　　6　　　　　　31
　　　　结构或联合中的成员个数　　　　127　　　　1023
　　　　函数调用中的参数个数　　　　　31　　　　　127



　　不再支持隐含式的int规则
　　删除了隐含式函数声明
　　对返回值的约束
　　　　C99中,非空类型函数必须使用带返回值的return语句.
　　扩展的整数类型
　　　　扩展类型 含义
　　　　int16_t 整数长度为精确16位
　　　　int_least16_t 整数长度为至少16位
　　　　int_fast32_t 最稳固的整数类型,其长度为至少32位
　　　　intmax_t 最大整数类型
　　　　uintmax_t 最大无符号整数类型
　　对整数类型提升规则的改进
　　　　C89中,表达式中类型为char,short int或int的值可以提升为int或unsigned int类型.
　　　　C99中,每种整数类型都有一个级别.例如:long long int 的级别高于int, int的级别高于char
等.在表达式中,其级别低于int或unsigned int的任何整数类型均可被替换成int或unsigned int类型.



(12)新增数据类型　
　　_Bool　
　　值是0或1。C99中增加了用来定义bool、true以及false宏的头文件夹<stdbool.h>，以便程序
员能够编写同时兼容于C与C++的应用程序。在编写新的应用程序时，应该使用
<stdbool.h>头文件中的bool宏。
　　_Complex and _Imaginary
　C99标准中定义的复数类型如下：float_Complex; float_Imaginary; double_Complex;
double_Imaginary; long double_Complex; long double_Imaginary.
<complex.h>头文件中定义了complex和imaginary宏,并将它们扩展为_Complex和_Imaginary,
因此在编写新的应用程序时,应该使用<stdbool.h>头文件中的complex和imaginary宏。
　　long long int
　　C99标准中引进了long long int（-(2e63 - 1)至2e63 - 1）和unsigned long long int（0 - 2e64
- 1）。long long int能够支持的整数长度为64位。

### C语言技巧

当然宏定义非常重要的，它可以帮助我们防止出错，提高代码的可移植性和可读性等。
下面列举一些成熟软件中常用得宏定义

1，防止一个头文件被重复包含
#ifndef COMDEF_H
#define COMDEF_H

//头文件内容 …
#endif

2，重新定义一些类型，防止由于各种平台和编译器的不同，而产生的类型字节数差异，方便移植。
typedef  unsigned long int  uint32;      ///< Unsigned 32 bit value

3，得到指定地址上的一个字节或字
#define  MEM_B( x )  ( *( (byte *) (x) ) )
#define  MEM_W( x )  ( *( (word *) (x) ) )

4，求最大值和最小值
#define  MAX( x, y )  ( ((x) > (y)) ? (x) : (y) )
#define  MIN( x, y )  ( ((x) < (y)) ? (x) : (y) )

5，得到一个field在结构体(struct)中的偏移量
#define FPOS( type, field )   ( (dword) &(( type *) 0)-> field )

6,得到一个结构体中field所占用的字节数
#define FSIZ( type, field ) sizeof( ((type *) 0)->field )

7，按照LSB格式把两个字节转化为一个word
#define  FLIPW( ray ) ( (((word) (ray)[0]) * 256) + (ray)[1] )

8，按照LSB格式把一个word转化为两个字节
#define  FLOPW( ray, val )
(ray)[0] = ((val) / 256);
(ray)[1] = ((val) & 0xFF)

9，得到一个变量的地址（word宽度）
#define  B_PTR( var )  ( (byte *) (void *) &(var) )
#define  W_PTR( var )  ( (word *) (void *) &(var) )

10，得到一个字的高位和低位字节
#define  WORD_LO(xxx)  ((byte) ((word)(var) & 255))
#define  WORD_HI(xxx)  ((byte) ((word)(var) >> 8))

11，返回一个比X大的最接近的8的倍数
#define RND8( x )       ((((x) + 7) / 8 ) * 8 )

12，将一个字母转换为大写
#define  UPCASE( c ) ( ((c) >= ’a' && (c) <= ’z') ? ((c) - 0×20) : (c) )

13，判断字符是不是10进值的数字
#define  DECCHK( c ) ((c) >= ’0′ && (c) <= ’9′)

14，判断字符是不是16进值的数字
#define  HEXCHK( c ) ( ((c) >= ’0′ && (c) <= ’9′) ||
((c) >= ’A' && (c) <= ’F') ||
((c) >= ’a' && (c) <= ’f') )

15，防止溢出的一个方法
#define  INC_SAT( val )  (val = ((val)+1 > (val)) ? (val)+1 : (val))

16，返回数组元素的个数
#define  ARR_SIZE( a )  ( sizeof( (a) ) / sizeof( (a[0]) ) )

17，对于IO空间映射在存储空间的结构，输入输出处理
#define inp(port)         (*((volatile byte *) (port)))
#define inpw(port)        (*((volatile word *) (port)))
#define inpdw(port)       (*((volatile dword *)(port)))

#define outp(port, val)   (*((volatile byte *) (port)) = ((byte) (val)))
#define outpw(port, val)  (*((volatile word *) (port)) = ((word) (val)))
#define outpdw(port, val) (*((volatile dword *) (port)) = ((dword) (val)))

18，使用一些宏跟踪调试
ANSI标准说明了五个预定义的宏名。它们是：
__LINE__
__FILE__
__DATE__
__TIME__
__STDC__

如果编译不是标准的，则可能仅支持以上宏名中的几个，或根本不支持。
记住编译程序 也许还提供其它预定义的宏名。
是行连接符，会将下一行和前一行连接成为一行，即将物理上的两行连接成逻辑上的一行
__FILE__ 是内置宏 代表源文件的文件名
__LINE__ 是内置宏，代表该行代码的所在行号
__DATE__宏指令含有形式为月/日/年的串，表示源文件被翻译到代码时的日期。
源代码翻译到目标代码的时间作为串包含在__TIME__ 中。串形式为时：分：秒。
如果实现是标准的，则宏__STDC__含有十进制常量1。如果它含有任何其它数，则实现是非标准的。

可以定义宏，例如:
当定义了_DEBUG，输出数据信息和所在文件所在行

#ifdef _DEBUG
#define DEBUGMSG(msg,date) printf(msg);printf(“%d%d%d”,date,_LINE_,_FILE_)
#else
#define DEBUGMSG(msg,date)
#endif

19，宏定义防止使用是错误
用小括号包含。
例如：#define ADD(a,b) （a+b）

用do{}while(0)语句包含多语句防止错误

例如：#define DO(a,b) a+b;
a++;
应用时：if(….)
DO(a,b); //产生错误
else
解决方法: 
#difne DO(a,b) do{a+b;a++;}while(0)

为什么需要do{…}while(0)形式?
总结了以下几个原因：

1)，空的宏定义避免warning:
#define foo() do{}while(0)
2)，存在一个独立的block，可以用来进行变量定义，进行比较复杂的实现。
3)，如果出现在判断语句过后的宏，这样可以保证作为一个整体来是实现：
#define foo(x)
action1();
action2();
在以下情况下：
if(NULL == pPointer)
    foo();
就会出现action2必然被执行的情况，而这显然不是程序设计的目的。


4)，以上的第3种情况用单独的{}也可以实现，但是为什么一定要一个do{}while(0)呢，看以下代码：
#define switch(x,y) {int tmp; tmp=x;x=y;y=tmp;}
if(x>y)
   switch(x,y);
else        //error, parse error before else
   otheraction();


在把宏引入代码中，会多出一个分号，从而会报错。
使用do{….}while(0) 把它包裹起来，成为一个独立的语法单元，从而不会与上下文发生混淆。同时因为绝大多数的编译器都能够识别do{…}while(0)这种无用的循环并进行优化，所以使用这种方法也不会导致程序的性能降低。

为什么很多linux内核中宏#defines用do { … } while(0)？
有很多原因：
（Dave Miller的说法）：
编译器对于空语句会给出告警，这是为什么#define FOO do{ }while(0);
给定一个基本块（局部可视域），定义很多局部变量；

（Ben Collins的说法）：
在条件代码中，允许定义复杂的宏。可以想像有很多行宏，如下代码

#define FOO(x)
printf(“arg is %sn”, x);
do_something_useful(x);
现在，想像下面的应用:
if (blah == 2)
FOO(blah);
展开后代码为:
if (blah == 2)
printf(“arg is %sn”, blah);
do_something_useful(blah);;
就像你看到的，if仅仅包含了printf()，而do_something_useful()调用是无条件调用。因此，如果用do { … } while(0)，结果是：
if (blah == 2)
do {
	printf(“arg is %sn”, blah);
	do_something_useful(blah);
} while (0);
这才是所期望的结果。
（Per Persson的说法）：
像 Miller and Collins指出的那样，需要一个块语句包含多个代码行和声明局部变量。但是，本质如下面例子代码：
#define exch(x,y) { int tmp; tmp=x; x=y; y=tmp; }
上面代码在有些时候却不能有效工作，下面代码是一个有两个分支的if语句：
if (x > y)
exch(x,y);               // Branch 1
else
do_something();      // Branch 2
展开后代码如下：
if (x > y)
{                // Single-branch if-statement!!!
	int tmp;            // The one and only branch consists
	tmp = x;           // of the block.
	x = y;
	y = tmp;
}
;                // empty statement
else                             // ERROR!!! “parse error before else”
do_something();
问题是分号（；）出现在块后面。解决这个问题可以用do{}while（0）：
if (x > y)
do {
int tmp;
tmp = x;
x = y;
y = tmp;
} while(0);
else
do_something();
（ Bart Trojanowski的说法）：
Gcc加入了语句解释，它提供了一个替代do-while-0块的方法。对于上面的解决方法如下，并且更加符合常理
#define FOO(arg) ({
typeof(arg) lcl;
lcl = bar(arg);
lcl;
})
这是一个奇怪的循环，它根本就只会运行一次，为什么不去掉外面的do{..}while结构呢？我曾一度在心里把它叫做“怪圈”。原来这也是非常巧妙的技巧。在工程中可能经常会引起麻烦，而上面的定义能够保证这些麻烦不会出现。下面是解释：
假设有这样一个宏定义
#define macro(condition)
if(condition) dosomething()
现在在程序中这样使用这个宏：
if(temp)
macro(i);
else
doanotherthing();
一切看起来很正常，但是仔细想想。这个宏会展开成：
if(temp)
if(condition) dosomething();
else
doanotherthing();
这时的else不是与第一个if语句匹配，而是错误的与第二个if语句进行了匹配，编译通过了，但是运行的结果一定是错误的。
为了避免这个错误，我们使用do{….}while(0) 把它包裹起来，成为一个独立的语法单元，从而不会与上下文发生混淆。同时因为绝大多数的编译器都能够识别do{…}while(0)这种无用的循环并进行优化，所以使用这种方法也不会导致程序的性能降低。



另一个讲解
这是为了含多条语句的宏的通用性
因为默认规则是宏定义最后是不能加分号的，分号是在引用的时候加上的
比如定义了一个宏fw(a,b)，那么在c文件里一定是这样引用
fw(a,b);
如果不用do…while，那么fw就得定义成:
#define fw(a,b) {read((a));write((b));}
那这样fw(a,b);展开后就成了:
{read(a);write(b);};
最后就多了个分号，这是语法错误
而定义成do…while的话，展开后就是:
do{read(a);write(b);}while(0);    完全正确
所以要写一个包含多条语句的宏的话，不用do…while是不可能的



宏中#和##的用法
一、一般用法
我们使用#把宏参数变为一个字符串,用##把两个宏参数贴合在一起.
用法:
＃include<cstdio>
＃include<climits>
using namespace std;

#define STR(s)     #s
#define CONS(a,b)  int(a##e##b)

int main()
{
	printf(STR(vck));        // 输出字符串vck
	printf(%dn, CONS(2,3));  // 2e3 输出:2000
	return 0;
}

二、当宏参数是另一个宏的时候
需要注意的是凡宏定义里有用’#'或’##’的地方宏参数是不会再展开.

1, 非’#'和’##’的情况
#define TOW      (2)
#define MUL(a,b) (a*b)

printf(%d*%d=%dn, TOW, TOW, MUL(TOW,TOW));
这行的宏会被展开为：
printf(%d*%d=%dn, (2), (2), ((2)*(2)));
MUL里的参数TOW会被展开为(2).

2, 当有’#'或’##’的时候
#define A          (2)
#define STR(s)     #s
#define CONS(a,b)  int(a##e##b)

printf(“int max: %sn”,  STR(INT_MAX));    // INT_MAX ＃include<climits>
这行会被展开为：
printf(“int max: %sn”, #INT_MAX);

printf(%sn, CONS(A, A));               // compile error
这一行则是：
printf(%sn, int(AeA));

INT_MAX和A都不会再被展开, 然而解决这个问题的方法很简单. 加多一层中间转换宏.
加这层宏的用意是把所有宏的参数在这层里全部展开, 那么在转换宏里的那一个宏(_STR)就能得到正确的宏参数.

#define A           (2)
#define _STR(s)     #s
#define STR(s)      _STR(s)                 // 转换宏
#define _CONS(a,b)  int(a##e##b)
#define CONS(a,b)   _CONS(a,b)       // 转换宏

printf(int max: %sn, STR(INT_MAX));          // INT_MAX，int型的最大值，为一个变量 ＃include<climits>
输出为: int max: 0x7fffffff
STR(INT_MAX) –>  _STR(0x7fffffff) 然后再转换成字符串；

printf(%dn, CONS(A, A));
输出为：200
CONS(A, A)  –>  _CONS((2), (2))  –> int((2)e(2))

三、’#'和’##’的一些应用特例
1、合并匿名变量名
#define  __ANONYMOUS1(type, var, line)  type  var##line
#define  _ANONYMOUS0(type, line)  __ANONYMOUS1(type, _anonymous, line)
#define  ANONYMOUS(type)  _ANONYMOUS0(type, __LINE__)
例：ANONYMOUS(static int);  即: static int _anonymous70;  70表示该行行号；
第一层：ANONYMOUS(static int);  –>  __ANONYMOUS0(static int, __LINE__);
第二层：–>  ___ANONYMOUS1(static int, _anonymous, 70);
第三层：–>  static int  _anonymous70;
即每次只能解开当前层的宏，所以__LINE__在第二层才能被解开；

2、填充结构
#define  FILL(a)   {a, #a}

enum IDD{OPEN, CLOSE};
typedef struct MSG{
IDD id;
const char * msg;
}MSG;

MSG _msg[] = {FILL(OPEN), FILL(CLOSE)};
相当于：
MSG _msg[] = {{OPEN, “OPEN”},
{CLOSE, ”CLOSE“}};

3、记录文件名
#define  _GET_FILE_NAME(f)   #f
#define  GET_FILE_NAME(f)    _GET_FILE_NAME(f)
static char  FILE_NAME[] = GET_FILE_NAME(__FILE__);

4、得到一个数值类型所对应的字符串缓冲大小
#define  _TYPE_BUF_SIZE(type)  sizeof #type
#define  TYPE_BUF_SIZE(type)   _TYPE_BUF_SIZE(type)
char  buf[TYPE_BUF_SIZE(INT_MAX)];
–>  char  buf[_TYPE_BUF_SIZE(0x7fffffff)];
–>  char  buf[sizeof 0x7fffffff];
这里相当于：
char  buf[11];
##5
#####################################################################
Ref:   https://gcc.gnu.org/onlinedocs/gcc-7.3.0/gcc.pdf
#####################################################################
##5.1 定义可变参数函数

##5.2 定义可变参数宏(第3种写法更好,防止不参数个数为0展开错误)
#define debug(format, ...)      printf (format, __VA_ARGS__)
#define debug(format, args...)  printf (format, args)
#define debug(format, args...)  printf (format, ##__VA_ARGS__)

for example:
#define CSTRACE(nLevel,format, ...)      CSDebug ("MMCP",nLevel,format, ##__VA_ARGS__)


*/

};



/********************************************************************************
                                <stddef.h>
********************************************************************************/
// The stddef header defines several standard definitions. Many of these definitions also appear in other
/*
Example:
#include <stdio.h>
#include <stddef.h>
 
struct S {
    char c;
    double d;
};
 
int main(void)
{
    printf("the first element is at offset %zu\n", offsetof(struct S, c));
    printf("the double is at offset %zu\n", offsetof(struct S, d));
}
*/


// This results in a constant integer of type size_t which is the offset in bytes of a structure member
// from the beginning of the structure. The member is given by member-designator, and the name of the
// structure is given in type.
/*
Example:
#include<stddef.h>
#include<stdio.h>
int main(void)
{
    struct user{
        char name[50];
        char alias[50];
        int level;
    };
    printf("level is the %d byte in the user structure.\n"),
    offsetof(struct user,level));
}

The output should be:
level is the 100 byte in the user structure
*/

class h_stddef
{
	const int offsetof;
};


/********************************************************************************
                                <assert.h>
********************************************************************************/
// The assert header is used for debugging purposes.
// Macros:
// assert();
// External References:
// NDEBUG

// The assert macro allows diagnostic information to be written to the standard error file.
// If expression evaluates to 0 (false), then the expression, sourcecode filename, and line number are sent
// to the standard error, and then calls the abort function. If the identifier NDEBUG ("no debug") is defined
// with #define NDEBUG then the macro assert does nothing.
// Common error outputting is in the form:
// Assertion failed: expression, file filename, line line-number

/*
Example1:
#include<stddef.h>
#include<assert.h>
void open_record(char *record_name)
{
    assert(record_name!=NULL);
}
int main(void)
{
    open_record(NULL);
}

**/


class h_assert
{
    void assert(int expression);
};



/********************************************************************************
                                <ctype.h>
********************************************************************************/
class module_char{
};


class h_ctype
{
	int isalnum(int character);
	int isalpha(int character);
	int iscntrl(int character);
	int isdigit(int character);
	int isgraph(int character);
	int islower(int character);
	int isprint(int character);
	int ispunct(int character);
	int isspace(int character);
	int isupper(int character);
	int isxdigit(int character);
	int tolower(int character);
	int toupper(int character);
	
	int isblank( int ch ); //Since C99
};





/********************************************************************************
                                <errno.h>
********************************************************************************/


// The errno header is used as a general error handler.
// Macros:
// EDOM
// ERANGE
// Variables:
// errno

class h_errno
{
    int errno;
};


/********************************************************************************
                                <float.h>
********************************************************************************/


/**
// A floating-point number is defined in the following manner:
 sign value E exponent
 Where sign is plus or minus, 
 value is the value of the number, 
 and exponent is the value of the exponent.
 The following values are defined with the #define directive. 
 These values are implementationspecific, but may not be any lower than what is given here.
 Note that in all instances 
 FLT refers to typefloat, 
 DBL refers to double, 
 LDBL refers to long double.
 
C 标准库的 float.h 头文件包含了一组与浮点值相关的依赖于平台的常量。
这些常量是由 ANSI C 提出的，这让程序更具有可移植性。在讲解这些常量之前，
最好先弄清楚浮点数是由下面四个元素组成的：
组件  组件描述
S   符号 ( +/- )
b   指数表示的基数，2 表示二进制，10 表示十进制，16 表示十六进制，等等...
e   指数，一个介于最小值 emin 和最大值 emax 之间的整数。
p   精度，基数 b 的有效位数

基于以上 4 个组成部分，一个浮点数的值如下：
floating-point = ( S ) p x be
或
floating-point = (+/-) precision x baseexponent

下面的值是特定实现的，且是通过 #define 指令来定义的，这些值都不得低于下边所给出的值。
请注意，所有的实例 
FLT 是指类型 float，
DBL 是指类型 double，
LDBL 是指类型 long double。
Example:

#include <stdio.h>
#include <float.h>

int main () {
  printf("float:\n" );
    printf("FLT_DIG = %d\n",FLT_DIG );
    printf("FLT_EPSILON = %.10e\n",FLT_EPSILON );
    printf("FLT_MANT_DIG = %.10e\n",FLT_MANT_DIG );
    // printf("FLT_RADIX = %d\n",FLT_RADIX );
    // printf("FLT_ROUNDS = %d\n",FLT_ROUNDS );
    printf("FLT_MAX = %.10e\n",FLT_MAX );
    printf("FLT_MIN = %.10e\n",FLT_MIN );
    printf("FLT_MAX_10_EXP = %.10e\n",FLT_MAX_10_EXP );
    printf("FLT_MIN_10_EXP = %.10e\n",FLT_MIN_10_EXP );
    printf("FLT_MAX_EXP = %.10e\n",FLT_MAX_EXP );
    printf("FLT_MIN_EXP = %.10e\n",FLT_MIN_EXP );
  
    printf("double:\n" );
    printf("DBL_DIG = %d\n",DBL_DIG );
    printf("DBL_EPSILON = %.10e\n",DBL_EPSILON );
    printf("DBL_MANT_DIG = %.10e\n",DBL_MANT_DIG );
    printf("DBL_MAX = %.10e\n",DBL_MAX );
    printf("DBL_MIN = %.10e\n",DBL_MIN );
    printf("DBL_MAX_10_EXP = %.10e\n",DBL_MAX_10_EXP );
    printf("DBL_MIN_10_EXP = %.10e\n",DBL_MIN_10_EXP );
    printf("DBL_MAX_EXP = %.10e\n",DBL_MAX_EXP );
    printf("DBL_MIN_EXP = %.10e\n",DBL_MIN_EXP );
  
    printf("long double:\n" );
    printf("LDBL_DIG = %d\n",LDBL_DIG );
    printf("LDBL_EPSILON = %.10e\n",LDBL_EPSILON );
    printf("LDBL_MANT_DIG = %.10e\n",LDBL_MANT_DIG );
    printf("LDBL_MAX = %.e\n",LDBL_MAX );
    printf("LDBL_MIN = %.e\n",LDBL_MIN );
    printf("LDBL_MAX_10_EXP = %.10e\n",LDBL_MAX_10_EXP );
    printf("LDBL_MIN_10_EXP = %.10e\n",LDBL_MIN_10_EXP );
    printf("LDBL_MAX_EXP = %.10e\n",LDBL_MAX_EXP );
    printf("LDBL_MIN_EXP = %.10e\n",LDBL_MIN_EXP );
    
    return 0;
}

**/


class h_float
{

};


/********************************************************************************
                                <limits.h>
********************************************************************************/
// The limits header defines the characteristics of variable types.
class h_limits
{
};


/********************************************************************************
                                <locale.h>
********************************************************************************/

// The locale header is useful for setting location specific information.
// Variables:
// struct lconv
// Macros:
// NULL
// LC_ALL
// LC_COLLATE
// LC_CTYPE
// LC_MONETARY
// LC_NUMERIC
// LC_TIME

/*
Example:
#include<locale.h>
#include<stdio.h>
int main(void)
{
    struct lconv locale_structure;
    struct lconv *locale_ptr=&locale_structure;
    locale_ptr=localeconv();
    printf("Decimal point: %s",locale_ptr->decimal_point);
    printf("Thousands Separator: %s",locale_ptr->thousands_sep);
    printf("Grouping: %s",locale_ptr->grouping);
    printf("International Currency Symbol: %s",locale_ptr->int_curr_symbol);
    printf("Currency Symbol: %s",locale_ptr->currency_symbol);
    printf("Monetary Decimal Point: %s",locale_ptr->mon_decimal_point);
    printf("Monetary Thousands Separator: %s",locale_ptr->mon_thousands_sep);
    printf("Monetary Grouping: %s",locale_ptr->mon_grouping);
    printf("Monetary Positive Sign: %s",locale_ptr->positive_sign);
    printf("Monetary Negative Sign: %s",locale_ptr->negative_sign);
    printf("Monetary Intl Decimal Digits: %c",locale_ptr->int_frac_digits);
    printf("Monetary Decimal Digits: %c",locale_ptr->frac_digits);
    printf("Monetary + Precedes: %c",locale_ptr->p_cs_precedes);
    printf("Monetary + Space: %c",locale_ptr->p_sep_by_space);
    printf("Monetary - Precedes: %c",locale_ptr->n_cs_precedes);
    printf("Monetary - Space: %c",locale_ptr->n_sep_by_space);
    printf("Monetary + Sign Posn: %c",locale_ptr->p_sign_posn);
    printf("Monetary - Sign Posn: %c",locale_ptr->n_sign_posn);
}
*/
class h_locale
{
    char *setlocale(int category, const char *locale);
    struct lconv *localeconv(void);
};


/********************************************************************************
                                <math.h>
********************************************************************************/

// 2.7 math.h
// The math header defines several mathematic functions.
// Macros:
// HUGE_VAL

// 2.7.1 Error Conditions
// All math.h functions handle errors similarly.
// In the case that the argument passed to the function exceeds the range of that function, then the variable
// errno is set to EDOM. The value that the function returns is implementation specific.
// In the case that the value being returned is too large to be represented in a double, then the function
// returns the macro HUGE_VAL, and sets the variable errno to ERANGE to represent an overflow. If the
// value is too small to be represented in a double, then the function returns zero. In this case whether or
// not errno is set to ERANGE is implementation specific.
// errno, EDOM, and ERANGE are defined in the errno.h header.
// Note that in all cases when it is stated that there is no range limit, it is implied that the value is limited by
// the minimum and maximum values of type double.

class h_math
{

    double acos(double x);
    double asin(double x);
    double atan(double x);
    double atan2(double y, double x);

    double cos(double x);
    double cosh(double x);
    double sin(double x);
    double sinh(double x);
    double tan(double x);
    double tanh(double x);
    double exp(double x);
    double frexp(double x, int *exponent);
    double ldexp(double x, int exponent);
    double log(double x);
    double log10(double x);
    double modf(double x, double *integer);
    double pow(double x, double y);
    double sqrt(double x);

    double ceil(double x);
    double fabs(double x);
    double floor(double x);
    double fmod(double x, double y);
};


/********************************************************************************
 //                                <setjmp.h>
********************************************************************************/
// The setjmp header is used for controlling low-level calls and returns to and from functions.
typedef language_c_type jmp_buf;

// Saves the environment into the variable environment. If a non-zero value is returned, then this indicates
// that the point in the sourcecode was reached by a longjmp. Otherwise zero is returned indicating the
// environment has been saved.
int setjmp(jmp_buf environment);

// Causes the environment to be restored from a setjmp call where the environment variable had been
// saved. It causes execution to goto the setjmp location as if setjmp had returned the value of the
// variable value. The variable value cannot be zero. However, if zero is passed, then 1 is replaced. If the
// function where setjmp was called has terminated, then the results are undefined.
void longjmp(jmp_buf environment, int value);


/*
Example:
#include<setjmp.h>
#include<stdio.h>
void some_function(jmp_buf env_buf)
{
    longjmp(env_buf,5);
}
int main(void)
{
    int value;
    jmp_buf environment_buffer;
    value=setjmp(environment_buffer);
    if(value!=0)
    {
        printf("Reached this point from a longjmp with value=%d.
        \n",value);
        exit(0);
    }
    printf("Calling function.\n");
    some_function(environment_buffer);
    return 0;
}

The output from this program should be
Calling function.
Reached this point from a longjmp with value=5.

*/
class h_setjmp
{

    int setjmp(jmp_buf environment);
    void longjmp(jmp_buf environment, int value);
};

/********************************************************************************
                                <signal.h>
********************************************************************************/
// The signal header provides a means to handle signals reported during a program's execution.
// Macros:

#define SIG_DFL //默认的信号处理程序。
#define SIG_ERR //表示一个信号错误。
#define SIG_IGN //忽视信号。

#define SIGABRT //异常终止，如调用abort()。
#define SIGFPE  //算术运算出错，如除数为0或溢出。
#define SIGILL  //非法函数映象，如非法指令。
#define SIGINT  //交互式信号，如中断。
#define SIGSEGV //非法访问存储器，如访问不存在的内存单元。
#define SIGTERM //发送给本程序的终止请求信号。



 typedef int sig_atomic_t;
// The sig_atomic_t type is of type int and is used as a variable in a signal handler. The SIG_
// macros are used with the signal function to define signal functions.

// SIG_DFL Default handler.
// SIG_ERR Represents a signal error.
// SIG_IGN Signal ignore.
// The SIG macros are used to represent a signal number in the following conditions:
// SIGABRT Abnormal termination (generated by the abort function).
// SIGFPE Floating-point error (error caused by division by zero, invalid operation,etc.).
// SIGILL Illegal operation (instruction).
// SIGINT Interactive attention signal (such as ctrl-C).
// SIGSEGV Invalid access to storage (segment violation, memory violation).
// SIGTERM Termination request.


// Controls how a signal is handled. sig represents the signal number compatible with the SIG macros.
// func is the function to be called when the signal occurs. If func is SIG_DFL, then the default handler is
// called. If func is SIG_IGN, then the signal is ignored. If func points to a function, then when a signal is
// detected the default function is called (SIG_DFL), then the function is called. The function must take
// one argument of type int which represents the signal number. The function may terminate with
// return, abort, exit, or longjmp. When the function terminates execution resumes where it was
// interrupted (unless it was a SIGFPE signal in which case the result is undefined).
// If the call to signal is successful, then it returns a pointer to the previous signal handler for the specified
// signal type. If the call fails, then SIG_ERR is returned and errno is set appropriately.
void (*signal(int sig, void (*func)(int)))(int);

// Causes signal sig to be generated. The sig argument is compatible with the SIG macros.
// If the call is successful, zero is returned. Otherwise a nonzero value is returned.
int raise(int sig);
/*
Example:
#include<signal.h>
#include<stdio.h>
void catch_function(int);
int main(void)
{
    if(signal(SIGINT, catch_function)==SIG_ERR)
    {
        printf("An error occured while setting a signal handler.\n");
        exit(0);
    }
    printf("Raising the interactive attention signal.\n");
    if(raise(SIGINT)!=0)
    {
        printf("Error raising the signal.\n");
        exit(0);
    }
    printf("Exiting.\n");
    return 0;
}
void catch_function(int signal)
{
    printf("Interactive attention signal caught.\n");
}

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
void sighandler(int signum)
{
    printf("Catch a signal num is %d ...\n", signum);
    exit(1);
}

int main()
{
    signal(SIGINT, sighandler);
    signal(SIGINT, sighandler);
    while(1)
    {
        printf("start sleeping!\n");
        sleep(1);//unit is second
    }
    return 0;
}

The output from the program should be (assuming no errors):
Raising the interactive attention signal.
Interactive attention signal caught.
Exiting
*/
class h_signal
{

	void (*signal(int sig, void (*func)(int)))(int);
	int raise(int sig);
};


/********************************************************************************
                                <stdarg.h>
********************************************************************************/

// The stdarg header defines several macros used to get the arguments in a function when the number of
// arguments is not known.
// Macros:
// va_start();
// va_arg();
// va_end();
// va_copy();

 typedef language_c_type va_list;

// The va_list type is a type suitable for use in accessing the arguments of a function with the stdarg
// macros.
// A function of variable arguments is defined with the ellipsis (,...) at the end of the parameter list.

//这个宏初始化 ap 变量，它与 va_arg 和 va_end 宏是一起使用的。
//last_arg 是最后一个传递给函数的已知的固定参数，即省略号之前的参数。
void va_start(va_list ap, last_arg);
//这个宏检索函数参数列表中类型为 type 的下一个参数。
type va_arg(va_list ap, type);

//这个宏允许使用了 va_start 宏的带有可变参数的函数返回。
//如果在从函数返回之前没有调用 va_end，则结果为未定义。
void va_end(va_list ap);

// Since C99
void va_copy( va_list dest, va_list src );

class h_stdarg
{
    void va_start(va_list ap, last_arg);
    type va_arg(va_list ap, type);
    void va_end(va_list ap);
    void va_copy( va_list dest, va_list src );    

}


/*
Example:
#include<stdarg.h>
#include<stdio.h>
void sum(char *string, int num_args, ...);
int main(void)
{
    sum("The sum of 10+15+13 is %d.\n",3,10,15,13);
    return 0;
}
void sum(char *string, int num_args, ...)
{
    int sum=0;
    va_list ap;
    int loop;
    va_start(ap,num_args);
    for(loop=0;loop<num_args;loop++)
        sum+=va_arg(ap,int);

    printf(string,sum);
    va_end(ap);
}
*/




/********************************************************************************
                                <stdio.h>
********************************************************************************/

// The stdio header provides functions for performing input and output.
// Macros:
// NULL
// _IOFBF
// _IOLBF
// _IONBF
// BUFSIZ
// EOF
// FOPEN_MAX
// FILENAME_MAX
// L_tmpnam
// SEEK_CUR
// SEEK_END
// SEEK_SET
// TMP_MAX
// stderr
// stdin
// stdout

// ftell();
// fwrite();
// remove();
// rename();
// rewind();
// setbuf();
// setvbuf();
// tmpfile();
// tmpnam();
// fprintf();
// fscanf();
// printf();
// scanf();
// sprintf();
// sscanf();
// vfprintf();
// vprintf();
// vsprintf();
// fgetc();
// fgets();
// fputc();
// fputs();
// getc();
// getchar();
// gets();
// putc();
// putchar();
// puts();
// ungetc();
// perror();


// Variables:
// typedef size_t
// typedef FILE
// typedef fpos_t
/**
size_t is the unsigned integer result of the sizeof keyword.
FILE is a type suitable for storing information for a file stream.
fpos_t is a type suitable for storing any position in a file.
NULL is the value of a null pointer constant.
_IOFBF, _IOLBF, and _IONBF are used in the setvbuf function.
BUFSIZ is an integer which represents the size of the buffer used by the setbuf function.
EOF is a negative integer which indicates an end-of-file has been reached.
FOPEN_MAX is an integer which represents the maximum number of files that the system
can guarantee that can be opened simultaneously.
FILENAME_MAX is an integer which represents the longest length of a char array suitable
for holding the longest possible filename. If the implementation imposes no limit, then
this value should be the recommended maximum value.
L_tmpnam is an integer which represents the longest length of a char array suitable for
holding the longest possible temporary filename created by the tmpnam function.
SEEK_CUR, SEEK_END, and SEEK_SET are used in the fseek function.
TMP_MAX is the maximum number of unique filenames that the function tmpnam can
generate.
stderr, stdin, and stdout are pointers to FILE types which correspond to the
standard error, standard input, and standard output streams.
**/


typedef unsigned int FILE;
typedef long int fpos_t;
// fseek 3th arg using
#define SEEK_CUR  (0)
#define SEEK_END  (-1)
#define SEEK_SET  (1)

#define stdin   (FILE*)(0)
#define stdout   (FILE*)(1)
#define stderr   (FILE*)(2)

class h_stdio
{

    long int ftell(FILE *stream);
    size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
    int remove(const char *filename);
    int rename(const char *old_filename, const char *new_filename);
    void rewind(FILE *stream);

    void setbuf(FILE *stream, char *buffer);
    int setvbuf(FILE *stream, char *buffer, int mode, size_t size);
    FILE *tmpfile(void);
    char *tmpnam(char *str);

    int fprintf(FILE *stream, const char *format, ...);
    int fscanf(FILE *stream, const char *format, ...);
    int printf(const char *format, ...);
    int scanf(const char *format, ...);
    int sprintf(char *str, const char *format, ...);
    int sscanf(const char *str, const char *format, ...);
    int vfprintf(FILE *stream, const char *format, va_list arg);
    int vprintf(const char *format, va_list arg);
    int vsprintf(char *str, const char *format, va_list arg);

    int fgetc(FILE *stream);
    char *fgets(char *str, int n, FILE *stream);
    int fputc(int char, FILE *stream);
    int fputs(const char *str, FILE *stream);
    int getc(FILE *stream);
    int getchar(void);
    char *gets(char *str);
    int putc(int char, FILE *stream);
    int putchar(int char);
    int puts(const char *str);
    int ungetc(int char, FILE *stream);
    void perror(const char *str);
};

/********************************************************************************
                                <stdlib.h>
********************************************************************************/
// The stdlib header defines several general operation functions and macros.
// Macros:
// NULL
// EXIT_FAILURE
// EXIT_SUCCESS
// RAND_MAX
// MB_CUR_MAX
// Variables:
// typedef size_t
// typedef wchar_t
// struct div_t
// struct ldiv_t
// Functions:
// abort();
// abs();
// atexit();
// atof();
// atoi();
// atol();
// bsearch();
// calloc();
// div();
// exit();
// free();
// getenv();
// labs();
// ldiv();
// malloc();
// mblen();
// mbstowcs();
// mbtowc();
// qsort();
// rand();
// realloc();
// srand();
// strtod();
// strtol();
// strtoul();
// system();
// wcstombs();
// wctomb();
// 2.13.1 Variables and Definitions
// size_t is the unsigned integer result of the sizeof keyword.
// wchar_t is an integer type of the size of a wide character constant.
// div_t is the structure returned by the div function.
// ldiv_t is the structure returned by the ldiv function.
// NULL is the value of a null pointer constant.
// EXIT_FAILURE and EXIT_SUCCESS are values for the exit function to return termination status.
// RAND_MAX is the maximum value returned by the rand function.
// MB_CUR_MAX is the maximum number of bytes in a multibyte character set which cannot be larger than
// MB_LEN_MAX.


class h_stdlib
{
	// number string convert number
    double atof( const char* str );
	int 	  atoi( const char *str );		
	long	  atol( const char *str );		
	long long atoll( const char *str );


    double strtod(const char *str, char **endptr);
    long int strtol(const char *str, char **endptr, int base);
    unsigned long int strtoul(const char *str, char **endptr, int base);
    // mem managment 
    void *calloc(size_t nitems, size_t size);
    void free(void *ptr);
    void *malloc(size_t size);
    void *realloc(void *ptr, size_t size);
    //system
    void abort(void);
    int atexit(void (*func)(void));
    void exit(int status);
    char *getenv(const char *name);
    int system(const char *string);
    //sort && search
    void *bsearch(const void *key, const void *base, size_t nitems,
                    size_t size, int (*compar)(const void *, const void *));
    void qsort(void *base, size_t nitems, size_t size,
                int (*compar)(const void *, const void *));
	// absolute value
	int abs(int j);
	long int labs(long int j);
	long long int llabs(long long int j);
	intmax_t imaxabs(intmax_t j);

    div_t div(int numer, int denom);
    ldiv_t ldiv(long int numer, long int denom);
  
    int rand(void);
    void srand(unsigned int seed);
    
    int mblen(const char *str, size_t n);
    
    size_t mbstowcs(schar_t *pwcs, const char *str, size_t n);
    int mbtowc(whcar_t *pwc, const char *str, size_t n);
    size_t wcstombs(char *str, const wchar_t *pwcs, size_t n);
    int wctomb(char *str, wchar_t wchar); 
    
    //Since C11 safe version
    errno_t wctomb_s(int *restrict status, char *restrict s, rsize_t ssz, wchar_t wc);              
    errno_t mbstowcs_s(size_t *restrict retval, wchar_t *restrict dst,rsize_t dstsz, const char *restrict src, rsize_t len);
    errno_t wcstombs_s( size_t *restrict retval, char *restrict dst, rsize_t dstsz,const wchar_t *restrict src, rsize_t len );                  
};

/********************************************************************************
                                <math.h>
********************************************************************************/

class h_math
{

};



/********************************************************************************
                                <string.h>                              
********************************************************************************/
//The string header provides many functions useful for manipulating strings (character arrays).  

class h_string
{
    void *memchr(const void *str, int c, size_t n);
    int   memcmp(const void *str1, const void *str2, size_t n);
    void *memcpy(void *str1, const void *str2, size_t n);
    void *memmove(void *str1, const void *str2, size_t n);
    void *memset(void *str, int c, size_t n);
    
    char *strcat(char *str1, const char *str2);
    
    char *strncat(char *str1, const char *str2, size_t n);
    char *strchr(const char *str, int c);
    int   strcmp(const char *str1, const char *str2);
    
    int   strncmp(const char *str1, const char *str2, size_t n);
    int   strcoll(const char *str1, const char *str2);
    char *strcpy(char *str1, const char *str2);
    char *strncpy(char *str1, const char *str2, size_t n);
    size_t strcspn(const char *str1, const char *str2);
    char *strerror(int errnum);
    size_t strlen(const char *str);
    char *strpbrk(const char *str1, const char *str2);
    char *strrchr(const char *str, int c);
    size_t strspn(const char *str1, const char *str2);
    char *strstr(const char *str1, const char *str2);
    char *strtok(char *str1, const char *str2);
    size_t strxfrm (char *restrict to, const char *restrict from, size_t size);  
    
    long long atoll( const char *str ); //since C99
};

/********************************************************************************
                                <time.h>
********************************************************************************/
class h_time
{

    const int CLOCKS_PER_SEC;

    char *asctime(const struct tm *timeptr);
    clock_t clock(void);
    char *ctime(const time_t *timer);
    double difftime(time_t time1, time_t time2);
    struct tm *gmtime(const time_t *timer);
    struct tm *localtime(const time_t *timer);
    time_t mktime(struct tm *timeptr);
    size_t strftime(char *str, size_t maxsize, const char *format,const struct tm *timeptr);
    time_t time(time_t *timer);
};




//	Since C95 
//	<wchar.h>       (since C95)	Extended multibyte and wide character utilities
//	<wctype.h>      (since C95)	Functions to determine the type contained in wide character data
//	<iso646.h>      (since C95)	Alternative operator spellings

/********************************************************************************
                                <wchar.h> Since C95
********************************************************************************/

/**
Example:
#include <stdio.h>
#include <wchar.h>
#include <wctype.h>
int main ()
{
    int i = 0;
    wchar_t c = L'A';  //定义单个宽字符
    wchar_t str[] = L"C语言 Java Python\n";  //定义宽字符串
   
    //将大写字母转换为小写字母输出
    if(iswupper(c)) c = towlower(c);
    putwchar(c);
    putwchar(L'\n');
   
    //只输出字母和空白符
    while(str[i])
    {
        if(iswalpha(str[i]) || iswspace(str[i])) putwchar(str[i]);
        i++;
    }
    return 0;
}
**/


// Example:



class h_wchar{

	int iswalnum( wint_t ch );
	int iswalpha( wint_t ch );
	int iswlower( wint_t ch );
	int iswupper( wint_t ch );
	int iswdigit( wint_t ch );
	int iswxdigit( wint_t ch );
	int iswcntrl( wint_t ch );
	int iswgraph( wint_t ch );
	int iswspace( wint_t ch );
	int iswblank( wint_t ch );
	int iswprint( wint_t ch );
	int iswpunct( wint_t ch );
	int iswctype( wint_t wc, wctype_t desc );
	
	wctype_t wctype( const char* str );
	int    mbsinit( const mbstate_t* ps);
	int    wctob( wint_t c );
	size_t mbrlen( const char *s, size_t n, mbstate_t *ps );
	size_t mbrlen( const char *restrict s, size_t n, mbstate_t *restrict ps );
	size_t mbrlen( const char *s, size_t n, mbstate_t *ps );
	size_t mbrlen( const char *restrict s, size_t n, mbstate_t *restrict ps );
	size_t mbrtowc( wchar_t *restrict pwc, const char *restrict s, size_t n,
					mbstate_t *restrict ps );
					
	//size_t mbsrtowcs( wchar_t* dst, const char** src, size_t len, mbstate_t* ps );	//(since C95)
	size_t mbsrtowcs( wchar_t *restrict dst, const char **restrict src, size_t len,mbstate_t *restrict ps);	//(since C99)
	errno_t mbsrtowcs_s( size_t *restrict retval,wchar_t *restrict dst, rsize_t dstsz,const char **restrict src, rsize_t len,mbstate_t *restrict ps);//(since C11)


};

/********************************************************************************
                                <wctype.h>
********************************************************************************/

wint_t towlower( wint_t wc );
wint_t towupper( wint_t wc );
wint_t towctrans( wint_t wc, wctrans_t desc );
wctrans_t wctrans( const char* str );

class h_wctype
{
public:
    wint_t towlower( wint_t wc );
    wint_t towupper( wint_t wc );
    wint_t towctrans( wint_t wc, wctrans_t desc );
    wctrans_t wctrans( const char* str );
};
/********************************************************************************
                                <iso646.h>
********************************************************************************/

//	Since C99
//	<complex.h>     (since C99)	Complex number arithmetic
//	<fenv.h>        (since C99)	Floating-point environment
//	<inttypes.h>    (since C99)	Format conversion of integer types
//	<stdbool.h>     (since C99)	Boolean type
//	<stdint.h>      (since C99)	Fixed-width integer types
//	<tgmath.h>      (since C99)	Type-generic math (macros wrapping math.h and complex.h)

/********************************************************************************
                                <complex.h>
********************************************************************************/

/********************************************************************************
                                <fenv.h>
********************************************************************************/

/********************************************************************************
                               <inttypes.h>
********************************************************************************/

/********************************************************************************
                                <stdbool.h> 
********************************************************************************/
class h_stdbool
{

};

/********************************************************************************
                                <stdint.h> 
********************************************************************************/
class h_stdint
{
};

/********************************************************************************
                               <tgmath.h>
********************************************************************************/

//	Since C11
//	<stdalign.h>    (since C11)	alignas and alignof convenience macros
//	<stdatomic.h>   (since C11)	Atomic types
//	<stdnoreturn.h> (since C11)	noreturn convenience macros
//	<threads.h>     (since C11)	Thread library
//	<uchar.h>       (since C11)	UTF-16 and UTF-32 character utilities
/********************************************************************************
                                <stdalign.h>
********************************************************************************/

class h_stdalign
{
};
/********************************************************************************
                                <stdatomic.h>
********************************************************************************/
/*
Example:

#include <stdalign.h>
#include <stdio.h>
// every object of type struct sse_t will be aligned to 16-byte boundary
// (note: needs support for DR 444)
struct sse_t
{
  alignas(16) float sse_data[4];
};
 
// every object of type struct data will be aligned to 128-byte boundary
struct data {
  char x;
  alignas(128) char cacheline[128]; // over-aligned array of char, 
                                    // not array of over-aligned chars
};
 
int main(void)
{
    printf("sizeof(data) = %zu (1 byte + 127 bytes padding + 128-byte array)\n",
           sizeof(struct data));
 
    printf("alignment of sse_t is %zu\n", alignof(struct sse_t));
 
    alignas(2048) struct data d; // this instance of data is aligned even stricter
}
*/
class h_stdatomic
{
};

/********************************************************************************
                                <stdnoreturn.h>
********************************************************************************/

// The _Noreturn keyword appears in a function declaration and specifies that the function does not return 
// by executing the return statement or by reaching the end of the function body (it may return by 
// executing longjmp). If the function declared _Noreturn returns, the behavior is undefined. 
// A compiler diagnostic is recommended if this can be detected.
// The _Noreturn specifier may appear more than once in the same function declaration, 
// the behavior is the same as if it appeared once.

// This specifier is typically used through the convenience macro noreturn, which is provided 
// in the header stdnoreturn.h.

/*
Example:
The following functions are noreturn in the standard library:
abort()
exit()
_Exit()
quick_exit()
thrd_exit()
longjmp()
*/
// Specifies that the function does not return to its point of invocation.



/**
#include <stdlib.h>
#include <stdio.h>
#include <stdnoreturn.h>
 
// causes undefined behavior if i <= 0
// exits if i > 0
noreturn void stop_now(int i) // or _Noreturn void stop_now(int i)
{
    if (i > 0) exit(i);
}
 
int main(void)
{
  puts("Preparing to stop...");
  stop_now(2);
  puts("This code is never executed.");
}
**/

class h_stdnoreturn
{
};


/********************************************************************************
                                <threads.h> Since C11
********************************************************************************/
/**
 Example:
#include <stdio.h>
#include <time.h>
#include <threads.h>
 
// utility function: difference between timespecs in microseconds
double usdiff(struct timespec s, struct timespec e)
{
    double sdiff = difftime(e.tv_sec, s.tv_sec);
    long nsdiff = e.tv_nsec - s.tv_nsec;
    if(nsdiff < 0) return 1000000*(sdiff-1) + (1000000000L+nsdiff)/1000.0;
    else return 1000000*(sdiff) + nsdiff/1000.0;
}
 
// busy wait while yielding
void sleep_100us()
{
    struct timespec start, end;
    timespec_get(&start, TIME_UTC);
    do {
        thrd_yield();
        timespec_get(&end, TIME_UTC);
    } while(usdiff(start, end) < 100.0);
}
 
int main()
{
    struct timespec start, end;
    timespec_get(&start, TIME_UTC);
    sleep_100us();
    timespec_get(&end, TIME_UTC);
    printf("Waited for %.3f us\n", usdiff(start, end));
}
 **/


class h_threads
{
        //Thread support library
        int thrd_create( thrd_t *thr, thrd_start_t func, void *arg );
        int thrd_equal( thrd_t lhs, thrd_t rhs );
        thrd_t thrd_current(void);
        int thrd_sleep( const struct timespec* duration,struct timespec* remaining );
        void thrd_yield(void);
        noreturn void thrd_exit( int res );
        int thrd_detach( thrd_t thr );
        int thrd_join( thrd_t thr, int *res );

        //	Mutual exclusion
        int mtx_init( mtx_t* mutex, int type );
        int mtx_lock( mtx_t* mutex );
        int mtx_timedlock( mtx_t *restrict mutex,const struct timespec *restrict time_point );
        int mtx_trylock( mtx_t *mutex );
        int mtx_unlock( mtx_t *mutex );
        void mtx_destroy( mtx_t *mutex );
        void call_once( once_flag* flag, void (*func)(void) );

        //Condition variables
        int cnd_init( cnd_t* cond );
        int cnd_signal( cnd_t *cond );
        int cnd_broadcast( cnd_t *cond );
        int cnd_wait( cnd_t* cond, mtx_t* mutex );
        int cnd_timedwait( cnd_t* restrict cond, mtx_t* restrict mutex, const struct timespec* restrict time_point );
        void cnd_destroy( cnd_t* cond );

        //Thread-local storage
        int tss_create( tss_t* tss_key, tss_dtor_t destructor );
        void *tss_get( tss_t tss_key );
        int tss_set( tss_t tss_id, void *val );
        void tss_delete( tss_t tss_id );
};


/********************************************************************************
                                <uchar.h> Since C11
********************************************************************************/

/**
Example:
#include <stdio.h>
#include <locale.h>
#include <uchar.h>
 
mbstate_t state;
int main(void)
{
	setlocale(LC_ALL, "en_US.utf8");
	char in[] = u8"zß水🍌"; // or "z\u00df\u6c34\U0001F34C"
	size_t in_sz = sizeof in / sizeof *in;
 
	printf("Processing %zu UTF-8 code units: [ ", in_sz);
	for(size_t n = 0; n < in_sz; ++n) printf("%#x ", (unsigned char)in[n]);
	puts("]");
 
	char16_t out[in_sz];
	char *p_in = in, *end = in + in_sz;
	char16_t *p_out = out;
	size_t rc;
	while((rc = mbrtoc16(p_out, p_in, end - p_in, &state)))
	{
		if(rc == (size_t)-1)	  // invalid input
			break;
		else if(rc == (size_t)-2) // truncated input
			break;
		else if(rc == (size_t)-3) // UTF-16 high surrogate
			p_out += 1;
		else {
			p_in += rc;
			p_out += 1;
		};
	}
 
	size_t out_sz = p_out - out + 1;
	printf("into %zu UTF-16 code units: [ ", out_sz);
	for(size_t x = 0; x < out_sz; ++x) printf("%#x ", out[x]);
	puts("]");
}
**/

class h_uchar
{
    size_t mbrtoc16( char16_t * restrict pc16, const char * restrict s,size_t n, mbstate_t * restrict ps );
    size_t c16rtomb( char * restrict s, char16_t c16, mbstate_t * restrict ps );
    size_t mbrtoc32( char32_t restrict * pc32, const char * restrict s,size_t n, mbstate_t * restrict ps );
    size_t c32rtomb( char * restrict s, char32_t c32, mbstate_t * restrict ps );
};


#endif //end of __ISO_STANDARD_C_H
//end of file
